#include "pfunc_format.h"

#include <stdlib.h>
#include <stdio.h>
#ifdef WIN32
#include <Winsock2.h>
#include <assert.h> 
#else
#include <string.h>
#include <assert.h>
#endif

int pyfree::string2bytes(const char* pSrc, unsigned char* pDst, int nSrcLength)
{
	for (int i = 0; i < nSrcLength; i += 2)
	{
		if (*pSrc >= '0' && *pSrc <= '9')
			*pDst = (*pSrc - '0') << 4;
		else
			*pDst = (*pSrc - 'A' + 10) << 4;
		pSrc++;
		// 输出低4位
		if (*pSrc >= '0' && *pSrc <= '9')
			*pDst |= *pSrc - '0';
		else
			*pDst |= *pSrc - 'A' + 10;
		pSrc++;
		pDst++;
	}
	return (nSrcLength / 2);
};


int pyfree::bytes2string(const unsigned char* pSrc, char* pDst, int nSrcLength)
{
	const char tab[] = "0123456789ABCDEF";    // 0x0-0xf的字符查找表
	for (int i = 0; i < nSrcLength; i++)
	{
		*pDst++ = tab[*pSrc >> 4];
		*pDst++ = tab[*pSrc & 0x0f];
		pSrc++;
	}
	*pDst = '\0';
	return nSrcLength * 2;
};

char pyfree::HexToASCII(unsigned char data_hex)
{
	char ASCII_data;
	ASCII_data=data_hex & 0x0F;
	if (ASCII_data<10)
	{
		ASCII_data=ASCII_data+0x30;
	}else{
		ASCII_data=ASCII_data+0x37;
	}
	return ASCII_data;
};

void pyfree::HexGroupToString(char* OutStrBuffer, unsigned char* InHexBuffer,unsigned int HexLength)
{
	unsigned int i,k=0;
	for (i = 0; i < HexLength; i++)
	{
		OutStrBuffer[k++]=HexToASCII((InHexBuffer[i]>>4)&0x0F);
		OutStrBuffer[k++]=HexToASCII(InHexBuffer[i]&0x0F);
	}
	OutStrBuffer[k]='\0';
};

bool pyfree::StringToHexGroup(unsigned char *OutHexBuffer, char *InStrBuffer, unsigned int strLength)
{
	unsigned int i, k=0;
	unsigned char HByte,LByte;
	if(strLength%2 !=0){
		return false;
	}

	for(i=0; i<strLength; i=i+2)
	{
		if(InStrBuffer[i]>='0' && InStrBuffer[i]<='9')
		{
			HByte=InStrBuffer[i]-'0';
		}
		else if(InStrBuffer[i]>='A' && InStrBuffer[i]<='F')
		{
			HByte=InStrBuffer[i]-'A' +10;
		}
		else
		{
			HByte=InStrBuffer[i];
			return false;
		}
		HByte=HByte <<4;
		HByte = HByte & 0xF0;
		if(InStrBuffer[i+1]>='0' && InStrBuffer[i+1]<='9')
		{
			LByte=InStrBuffer[i+1]-'0';
		}
		else if(InStrBuffer[i+1]>='A' && InStrBuffer[i+1]<='F')
		{
			LByte=InStrBuffer[i+1]-'A' +10;
		}
		else
		{
			LByte=InStrBuffer[i];
			return false;
		}
		OutHexBuffer[k++]=HByte |LByte;
	}
	return true;
};

int pyfree::invernumber(const char* pSrc,char* pDst,int nSrcLength)
{
	int nDstLength = nSrcLength;
	char ch;
	for(int i=0; i<nSrcLength;i+=2){
		ch = *pSrc++;   // 保存先出现的字符
		*pDst++ = *pSrc++; // 复制后出现的字符
		*pDst++ = ch;   // 复制先出现的字符
	}
	if(nSrcLength & 1){
		*(pDst-2) = 'F'; // 补'F'
		nDstLength++;   // 目标串长度加1
	}
	*pDst = '\0';
	return nDstLength;
}

int pyfree::encodeucs2(const char* pSrc, unsigned char* pDst, int nSrcLength)
{
	int nDstLength;        // UNICODE宽字符数目
	wchar_t wchar[256]={0}; // UNICODE串缓冲区
	// setlocale(LC_ALL,"chs");
	nDstLength = (int)mbstowcs( wchar, pSrc, nSrcLength);
	for(int i=0; i<nDstLength; i++){     // 高低字节对调，输出
		*pDst++ = wchar[i] >> 8;         // 先输出高位字节
		*pDst++ = wchar[i] & 0xff;       // 后输出低位字节
	}
	// setlocale(LC_ALL,"C");
	return nDstLength * 2;
};

unsigned char pyfree::ToHex(unsigned char x)
{
	return  x > 9 ? x + 55 : x + 48;
};

unsigned char pyfree::FromHex(unsigned char x)
{
	unsigned char y;
	if (x >= 'A' && x <= 'Z')
	{
		y = x - 'A' + 10;
	}
	else if (x >= 'a' && x <= 'z')
	{
		y = x - 'a' + 10;
	}
	else if (x >= '0' && x <= '9')
	{
		y = x - '0';
	}
	else
	{
		assert(0);
	}
	return y;
};

std::string pyfree::UrlEncode(const std::string& str)
{
	std::string strTemp = "";
	size_t length = str.length();
	for (size_t i = 0; i < length; ++i)
	{
		if (isalnum((unsigned char)str[i]) ||
			(str[i] == '-') ||
			(str[i] == '_') ||
			(str[i] == '.') ||
			(str[i] == '~'))
			strTemp += str[i];
		else if (str[i] == ' ')
		{
			strTemp += "+";
		}
		else
		{
			strTemp += '%';
			strTemp += ToHex((unsigned char)str[i] >> 4);
			strTemp += ToHex((unsigned char)str[i] % 16);
		}
	}
	return strTemp;
}

std::string pyfree::UrlDecode(const std::string& str)
{
	std::string strTemp = "";
	size_t length = str.length();
	for (size_t i = 0; i < length; ++i)
	{
		if (str[i] == '+')
		{
			strTemp += ' ';
		}
		else if (str[i] == '%')
		{
			assert(i + 2 < length);
			unsigned char high = FromHex((unsigned char)str[++i]);
			unsigned char low = FromHex((unsigned char)str[++i]);
			strTemp += high * 16 + low;
		}
		else strTemp += str[i];
	}
	return strTemp;
}

void pyfree::strToHex16(char *in,unsigned char *out,int size)
{
	unsigned int ch;
	int index=0;
	while(sscanf(in,"%2x",&ch)!=EOF&&index<size)
	{
		out[index++]=ch;
		in+=2;
	}
	out[index<size?index:(size-1)]='\0';
};

void pyfree::strFromHex16(unsigned char *in,char *out,int size)
{
	int i=0;
	while('\0'!=in[i]&&(2*i<size))
	{
		//char ch[2]={0};
		sprintf(out+i*2,"%02x",in[i]);
		i++;
	}
	out[2*i<size?2*i:(size-1)]='\0';
};

struct Base64Date6
{
  unsigned int d4 : 6;
  unsigned int d3 : 6;
  unsigned int d2 : 6;
  unsigned int d1 : 6;
};
 
 
char pyfree::ConvertToBase64(char uc)
{
  if (uc < 26)
  {
    return 'A' + uc;
  }
  if (uc < 52)
  {
    return 'a' + (uc - 26);
  }
  if (uc < 62)
  {
    return '0' + (uc - 52);
  }
  if (uc == 62)
  {
    return '+';
  }
  return '/';
}

#ifdef __linux__
#define strcpy_s(buffer, size, arg) \
	do{ strcpy(buffer, arg); } while (0) 
#endif // __linux__
// base64的实现
void pyfree::EncodeBase64(char *dbuf, char *buf128, int len)
{
  struct Base64Date6 *ddd = NULL;
  int      i = 0;
  char     buf[256] = { 0 };
  char     *tmp = NULL;
  char     cc = '\0';
 
  memset(buf, 0, 256);
  strcpy_s(buf, 256, buf128);

  for (i = 1; i <= len / 3; i++)
  {
    tmp = buf + (i - 1) * 3;
    cc = tmp[2];
    tmp[2] = tmp[0];
    tmp[0] = cc;
    ddd = (struct Base64Date6 *)tmp;
    dbuf[(i - 1) * 4 + 0] = ConvertToBase64((unsigned int)ddd->d1);
    dbuf[(i - 1) * 4 + 1] = ConvertToBase64((unsigned int)ddd->d2);
    dbuf[(i - 1) * 4 + 2] = ConvertToBase64((unsigned int)ddd->d3);
    dbuf[(i - 1) * 4 + 3] = ConvertToBase64((unsigned int)ddd->d4);
  }
  if (len % 3 == 1)
  {
    tmp = buf + (i - 1) * 3;
    cc = tmp[2];
    tmp[2] = tmp[0];
    tmp[0] = cc;
    ddd = (struct Base64Date6 *)tmp;
    dbuf[(i - 1) * 4 + 0] = ConvertToBase64((unsigned int)ddd->d1);
    dbuf[(i - 1) * 4 + 1] = ConvertToBase64((unsigned int)ddd->d2);
    dbuf[(i - 1) * 4 + 2] = '=';
    dbuf[(i - 1) * 4 + 3] = '=';
  }
  if (len % 3 == 2)
  {
    tmp = buf + (i - 1) * 3;
    cc = tmp[2];
    tmp[2] = tmp[0];
    tmp[0] = cc;
    ddd = (struct Base64Date6 *)tmp;
    dbuf[(i - 1) * 4 + 0] = ConvertToBase64((unsigned int)ddd->d1);
    dbuf[(i - 1) * 4 + 1] = ConvertToBase64((unsigned int)ddd->d2);
    dbuf[(i - 1) * 4 + 2] = ConvertToBase64((unsigned int)ddd->d3);
    dbuf[(i - 1) * 4 + 3] = '=';
  }
  return;
}
